package com.fishingwithme.controllers;

import com.fishingwithme.domain.credit.CreditLevelRule;
import com.fishingwithme.domain.credit.CreditRecord;
import com.fishingwithme.domain.credit.CreditRule;
import com.fishingwithme.domain.credit.CreditService;
import com.fishingwithme.infrastructure.dtos.DTO;
import com.fishingwithme.infrastructure.dtos.credit.CreditAvailableDto;
import com.fishingwithme.infrastructure.dtos.credit.UserCreditDto;
import com.fishingwithme.infrastructure.utils.CommonUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/credit")
@Tag(name = "Credit Management", description = "APIs for credit system management, records, and levels")
public class CreditController {
    @Autowired
    private CreditService creditService;

    @GetMapping(path = "/isCreditAvailable")
    @Operation(
            summary = "Check credit availability for spot",
            description = "Check if credit can be collected for a specific fishing spot",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Credit availability checked successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody DTO<CreditAvailableDto> isCreditAvailable(
            @Parameter(description = "Fishing spot ID", required = true, example = "123")
            @RequestParam Long spotId){
        return DTO.success(creditService.isCreditAvailableForCollect(spotId));
    }

    @GetMapping(path = "/records/list")
    @Operation(
            summary = "Get credit records",
            description = "Retrieve paginated list of user's credit records",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Credit records retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = IPage.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody IPage<CreditRecord> list(
            @Parameter(description = "Page number", example = "1")
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @Parameter(description = "Page size", example = "10")
            @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1 || pageSize > 100) pageSize = 20;
        Long userId = CommonUtils.getUserId();
        return creditService.list(pageNum, pageSize, userId);
    }

    @GetMapping(path = "/get")
    @Operation(
            summary = "Get user credit information",
            description = "Retrieve current user's credit information and mark daily attendance",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User credit information retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = UserCreditDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody UserCreditDto get() {
        Long userId = CommonUtils.getUserId();
        creditService.dailyMark(userId);
        return creditService.get(userId);
    }

    @GetMapping(path = "/skipAds")
    @Operation(
            summary = "Set ad skip preference",
            description = "Set user preference for skipping advertisements",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Ad skip preference updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody DTO<Boolean> skipAds(
            @Parameter(description = "Whether to skip ads", required = true, example = "true")
            @RequestParam Boolean skipAds) {
        return DTO.success(creditService.skipAds(skipAds, CommonUtils.getUserId()));
    }

    @GetMapping(path = "/getCreditLvls")
    @Operation(
            summary = "Get credit level rules",
            description = "Retrieve list of credit level rules for the current user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Credit level rules retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody DTO<List<CreditLevelRule>> getCreditLvls() {
        Long userId = CommonUtils.getUserId();
        return DTO.success(creditService.getCreditLvls(userId));
    }

    @GetMapping(path = "/getCreditRules")
    @Operation(
            summary = "Get credit rules",
            description = "Retrieve paginated list of credit rules",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Credit rules retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = IPage.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody IPage<CreditRule> getCreditRules(
            @Parameter(description = "Page number", example = "1")
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @Parameter(description = "Page size", example = "10")
            @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1 || pageSize > 100) pageSize = 20;
        Long userId = CommonUtils.getUserId();
        return creditService.getCreditRules(pageNum, pageSize, userId);
    }

    @GetMapping(path = "/setCredit")
    @Operation(
            summary = "Set credit for spot",
            description = "Set credit value for a specific fishing spot",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Credit set successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody DTO<Boolean> setCredit(
            @Parameter(description = "Fishing spot ID", required = true, example = "123")
            @RequestParam Long spotId, 
            @Parameter(description = "Credit value to set", required = true, example = "10")
            @RequestParam Integer credit) {
        return DTO.success(creditService.setCredit(spotId,credit));
    }

}
